package com.gitee.zhangchenyan.takin;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.Cleanup;
import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;

import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

@Mojo(name = "MybatisPluginGeneratorMojo")
public class MybatisPluginGeneratorMojo extends AbstractMojo {

    private static final String _userDir = System.getProperty("user.dir");

    @SneakyThrows
    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        Properties properties = new Properties();
        @Cleanup InputStream inputStream = new FileInputStream(_userDir + "/src/main/resources/takin-generator.properties");
        properties.load(inputStream);
        _entries = properties.entrySet();
        FastAutoGenerator.create(getValue("takin.generator.db.url"), getValue("takin.generator.db.username"), getValue("takin.generator.db.password"))
                // 全局配置
                .globalConfig((scanner, builder) ->
                                builder.author(getValue("takin.generator.author"))
                                        .outputDir(getValue("takin.generator.output.dir"))
                                        .enableSwagger() // 开启 swagger 模式
                        //.fileOverride() // 覆盖已生成文件
                )
                // 包配置
                .packageConfig((scanner, builder) ->
                        builder.parent(getValue("takin.generator.parent"))
                )
                // 策略配置
                .strategyConfig((scanner, builder) -> builder.addInclude(getTables(getValue("takin.generator.db.tables")))
                        .controllerBuilder().enableRestStyle().enableHyphenStyle()
                        .entityBuilder()
                        .enableLombok()
                        .superClass("com.gitee.zhangchenyan.takin.service.BaseEntity")
                        .addIgnoreColumns("id", "creation_time", "last_modification_time", "deletiont_time", "creator_id", "last_modifier_id", "deleter_id", "remark", "is_deleted")
                        .serviceBuilder().superServiceClass("com.gitee.zhangchenyan.takin.service.BaseService").superServiceImplClass("com.gitee.zhangchenyan.takin.service.BaseServiceImpl")
                        .build())
                .execute();
        for (String table : getTables(getValue("takin.generator.db.tables"))) {
            String entityName = getEntityName(table);
            execute(getValue("takin.generator.parent"), entityName, getValue("takin.generator.output.dir"));
        }
    }

    @SneakyThrows
    private void execute(String classPath, String className, String dir) {
        // step1 创建freeMarker配置实例
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_21);
        // step2 获取模版路径
        configuration.setClassForTemplateLoading(MybatisPluginGeneratorMojo.class, "/");
        // step3 创建数据模型
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("classPath", classPath);
        dataMap.put("className", className);
        // step4 加载模版文件
        Template takinServiceTemplate = configuration.getTemplate("TakinService.ftl");
        File takinServiceDocFile = new File(dir + "\\" + "I" + className + "Service.java");
        @Cleanup Writer takinServiceOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(takinServiceDocFile)));
        takinServiceTemplate.process(dataMap, takinServiceOut);

        Template takinPageParamTemplate = configuration.getTemplate("TakinPageParam.ftl");
        File takinPageParamDocFile = new File(dir + "\\" + className + "PageParam.java");
        @Cleanup Writer takinPageParamOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(takinPageParamDocFile)));
        takinPageParamTemplate.process(dataMap, takinPageParamOut);

        Template takinServiceImpTemplate = configuration.getTemplate("TakinServiceImp.ftl");
        File takinServiceImpDocFile = new File(dir + "\\" + className + "ServiceImpl.java");
        @Cleanup Writer takinServiceImpDocFileOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(takinServiceImpDocFile)));
        takinServiceImpTemplate.process(dataMap, takinServiceImpDocFileOut);

        Collection<File> files = FileUtils.listFiles(new File(dir), new String[]{"java","xml"}, true);
        for (File file : files) {
            try {
                FileUtils.copyFile(file, new File(dir + "\\" + file.getName()));
            } catch (Exception e) {
            }
        }
        String removeDir = getValue("takin.generator.parent").split("\\.")[0];
        FileUtils.deleteDirectory(new File(dir + "\\" + removeDir));
        System.out.println("Service 文件创建成功 !");

    }

    private String getEntityName(String tableName) {
        String[] tables = tableName.split("_");
        StringBuilder entityName = new StringBuilder();
        for (String table : tables) {
            entityName.append(table.substring(0, 1).toUpperCase()).append(table.substring(1));
        }
        return entityName.toString();
    }

    private Set<Map.Entry<Object, Object>> _entries = null;

    @SneakyThrows
    private String getValue(String key) {
        for (Map.Entry<Object, Object> entry : _entries) {
            if (entry.getKey().equals(key)) {
                String value = (String) entry.getValue();
                value = URLEncoder.encode(value, "ISO-8859-1");
                value = URLDecoder.decode(value, "GBK");
                return value;
            }
        }
        return "";
    }

    // 处理 all 情况
    private List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }
}
